﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.Mvc;
using FeedsLibrary;
using FeedsLibrary.Feeds;
using FeedsLibrary.Feeds.Abstract;
using ThirdPrize.Classes;
using ThirdPrize.Models;
using log4net;

namespace ThirdPrize.Controllers
{
    public class RssController : Controller
    {
        private static readonly ILog RssLog = LogManager.GetLogger
            ("Rss");

        private TagCloudCache _cache = new TagCloudCache();

        private string GetExceptionString(Exception e)
        {
            StringBuilder s = new StringBuilder(e.Message).Append(Environment.NewLine).AppendLine(e.StackTrace);

            return s.ToString();
        }

        //
        // GET: /Rss/
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Error()
        {
            return View();
        }

        public ActionResult Refreshed()
        {
            return View();
        }

        #region tag cloud

        public ActionResult TagCloud(string topic)
        {
            RssLog.Info(String.Format("TagCloud for {0}", topic));

            TagCloudModel model = new TagCloudModel();
            if (!_cache.IsSet(topic))
            {
                TagCloud t = new TagCloud();
                model = t.CreateModel(topic);
                _cache.Set(topic, model, 1440);
            }
            else
            {
                model = _cache.Get(topic);
            }

            return View(model);
        }

        public ActionResult Stories(string topic, string tag)
        {
            StoriesModel s =new StoriesModel();

            TagCloudModel m = _cache.Get(topic);
            if (tag==null)
            {
                s.Stories = m.AllStories;
                s.Tag = topic;

            }
            else
            {
                if (m.TagsAndStories.ContainsKey(tag))
                {
                    s.Stories = m.TagsAndStories[tag];
                }
                s.Tag = tag;
                
            }

            return View(s);
        }

        #endregion

        #region viewers

        public ActionResult AppleViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "Apple", @Tag=""});
        }

        public ActionResult AltCoinViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "AltCoin", @Tag = "" });
        }

        public ActionResult MusicViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "Music", @Tag = "" });
        }

        public ActionResult TechnologyViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "Technology", @Tag = "" });
        }

        public ActionResult VideoGamesViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "Video_Games", @Tag = "" });
        }

        public ActionResult WindowsPhoneViewer()
        {
            return RedirectToAction("Stories", "Rss", new { @Topic = "Windows_Phone", @Tag = "" });
        }

        #endregion

        #region tag clouds

        public ActionResult MusicTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "Music" });
        }

        public ActionResult AltCoinTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "AltCoin" });
        }

        public ActionResult AppleTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "Apple" });
        }

        public ActionResult TechnologyTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "Technology" });
        }

        public ActionResult VideoGamesTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "Video_Games" });
        }

        public ActionResult WindowsPhoneTagCloud()
        {
            return RedirectToAction("TagCloud", "Rss", new { @Topic = "Windows_Phone" });
        }

        #endregion

        /// <summary>
        /// Refresh the RSS feed
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        public ActionResult RssRefresh()
        {
            RssLog.Info("RssRefresh called");

            try
            {
                RssRefreshCore(Server.MapPath("~"));
            }
            catch (Exception e)
            {
                RssLog.Error(GetExceptionString(e));
            }
            return RedirectToAction("Refreshed", "Rss");
        }

        [AllowAnonymous]
        public ActionResult RssGetData(string topic, string user)
        {
            RssLog.Info(String.Format("RssGetData called - {0} - {1}", topic, user));

            string path = Path.Combine(Server.MapPath("~"), topic + ".zip");
            ActionResult result;

            try
            {
                if (System.IO.File.Exists(path))
                {
                    result = new FilePathResult(path, "application/zip");
                }
                else
                {
                    result = new EmptyResult();
                }

            }
            catch (Exception)
            {
                result = new EmptyResult();
            }
            return result;
        }

        public void RssRefreshCore(string path)
        {
            RssLog.Info("RssRefreshCore called");

            //read the settings
            var settings = new UserSettings(path);

            //allocate the array
            var allFeeds = new List<IChannel>();

            //create the compound feeds
            for (int f = 0; f < settings.FeedCount(); f++)
            {
                IChannel c = new CompoundChannel(settings.FeedDetails(f), DateTime.Now, path);
                allFeeds.Add(c);
                c.Save(Path.Combine(path, c.FileName + ".xml"));

                if (_cache.IsSet(c.FileName))
                {
                    _cache.Invalidate(c.FileName);
                }
                TagCloud t = new TagCloud();
                TagCloudModel model = t.CreateModel(c.FileName);
                _cache.Set(c.FileName, model, 1440);
            }
        }
    }
}